﻿#include "HttpServer.h"
#include "../Settings.h"
#include "../../Shared/Language.h"
#include "../../Shared/ClientPackets.h"
#include "../MirEnvir/Envir.h"
#include "../../Shared/ServerPackets.h"
#include "../../Shared/Enums.h"

using namespace Server::MirEnvir;
namespace S = ServerPackets;

namespace Server::Library::Utils
{

    HttpServer::HttpServer()
    {
        Host = Settings::HTTPIPAddress;
    }

    void HttpServer::Start()
    {
        _thread = new Thread([&] () {Listen();});
        _thread->Start();
    }

    void HttpServer::Stop()
    {
        HttpService::Stop();
        if (_thread != nullptr)
        {
            _thread->Abort();
        }
    }

    void HttpServer::OnGetRequest(HttpListenerRequest *request, HttpListenerResponse *response)
    {
        auto url = request->Url->PathAndQuery;
        if (url.find("?") != std::string::npos)
        {
            url = url.substr(0, (int)url.find("?", StringComparison::Ordinal));
            url = StringHelper::toLower(url);
        }
        try
        {
//C# TO C++ CONVERTER NOTE: The following 'switch' operated on a string and was converted to C++ 'if-else' logic:
//            switch (url)
//ORIGINAL LINE: case "/":
            if (url == "/")
            {
                    WriteResponse(response, GameLanguage::GameName);
            }
//ORIGINAL LINE: case "/newaccount":
            else if (url == "/newaccount")
            {
                    auto id = request->QueryString["id"];
                    auto psd = request->QueryString["psd"];
                    auto email = request->QueryString["email"];
                    auto name = request->QueryString["name"];
                    auto question = request->QueryString["question"];
                    auto answer = request->QueryString["answer"];
                    auto ip = request->QueryString["ip"];
                    auto p = new ClientPackets::NewAccount();
                    p->AccountID = id;
                    p->Password = psd;
                    p->EMailAddress = email;
                    p->UserName = name;
                    p->SecretQuestion = question;
                    p->SecretAnswer = answer;
                    auto result = Envir::getMain()->HTTPNewAccount(p, ip);
                    WriteResponse(response, std::to_string(result));
            }
//ORIGINAL LINE: case "/addnamelist":
            else if (url == "/addnamelist")
            {
                    id = request->QueryString["id"];
                    auto fileName = request->QueryString["fileName"];
                    AddNameList(id, fileName);
                    WriteResponse(response, "true");
            }
//ORIGINAL LINE: case "/broadcast":
            else if (url == "/broadcast")
            {
                    auto msg = request->QueryString["msg"];
                    if (msg.length() < 5)
                    {
                        WriteResponse(response, "short");

//C# TO C++ CONVERTER TODO TASK: A 'delete p' statement was not added since p was passed to a method or constructor. Handle memory management manually.
                        return;
                    }
                    S::Chat *tempVar = new S::Chat();
                    tempVar->Message = StringHelper::trim(msg);
                    tempVar->Type = ChatType::Shout2;
                    Envir::getMain()->Broadcast(tempVar);
                    WriteResponse(response, "true");
            }
            else
            {
                    WriteResponse(response, "error");

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was passed to a method or constructor. Handle memory management manually.
//C# TO C++ CONVERTER TODO TASK: A 'delete p' statement was not added since p was passed to a method or constructor. Handle memory management manually.
            }
        }
        catch (const std::runtime_error &error)
        {
            WriteResponse(response, "request error: " + error);
        }
    }

    void HttpServer::AddNameList(const std::string &playerName, const std::string &fileName)
    {
        fileName = FileSystem::combine(Settings::NameListPath, fileName);
        auto sDirectory = FileSystem::getDirectoryName(fileName);
//C# TO C++ CONVERTER TODO TASK: Throw expressions are not converted by C# to C++ Converter:
//ORIGINAL LINE: Directory.CreateDirectory(sDirectory ?? throw new InvalidOperationException());
        InvalidOperationException tempVar();
        FileSystem::createDirectory((sDirectory != "") ? sDirectory : throw &tempVar);
        if (!FileSystem::fileExists(fileName))
        {
            File::Create(fileName)->Close();
        }

        auto tempString = fileName;
        if (File::ReadAllLines(tempString).All([&] (std::any t)
        {
            return playerName != t;
        }))
        {
//C# TO C++ CONVERTER NOTE: The following 'using' block is replaced by its C++ equivalent:
//ORIGINAL LINE: using (var line = File.AppendText(tempString))
            {
                auto line = File::AppendText(tempString);
                line.WriteLine(playerName);
            }
        }
    }

    void HttpServer::OnPostRequest(HttpListenerRequest *request, HttpListenerResponse *response)
    {
        std::cout << "POST request: " << request->Url << std::endl;
    }
}
